Fix: 旧版 libmpv(armeabi-v7a Android TV)播放含独立音频流的视频时黑屏无声音#71
Fix: 旧版 libmpv(armeabi-v7a Android TV)播放含独立音频流的视频时黑屏无声音#71TakChen wants to merge 7 commits intoStarfallan:mainfrom
Conversation
移除 kDebugMode/Platform.isAndroid 的条件限制,使音频标准化在所有平台生效<br> 精简旧版 mpv 兼容性错误处理,去除冗余的错误上报与调试日志<br> 更新注释以准确描述 change-list 规避方案
移除对旧版 libmpv 设备(如部分 Android TV armeabi-v7a)产生的兼容性错误日志的过滤代码,包括 loadfile options 参数解析错误及 invalid parameter 错误的特殊处理,统一交由错误上报流程处理
There was a problem hiding this comment.
Pull request overview
该 PR 针对部分 Android TV(armeabi-v7a)设备内置旧版 libmpv 在播放“视频 + 独立音频流”场景下无声音的问题,调整了向 mpv 传递 audio-files/lavfi-complex 的方式以兼容旧版 loadfile 行为。
Changes:
- Android 平台跳过通过
extras传递audio-files,改为使用change-list,并在open()后再补设一次以对抗旧版loadfile replace清除属性的问题 change-list audio-files set的 URL 冒号统一转义为\:(针对旧版 mpv 的解析兼容)lavfi-complex恢复为不再受kDebugMode || Platform.isAndroid限制,并新增通过命令set lavfi-complex的设置路径
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| final escapedAudio = Platform.isWindows | ||
| ? audio.replaceAll(';', r'\;') | ||
| : audio.replaceAll(':', r'\:'); | ||
| // Android 上旧版 libmpv(如部分 Android TV armeabi-v7a 设备)不支持 loadfile 的 options 参数, | ||
| // 传入 extras 会导致整个 loadfile 命令失败(视频和音频都无法加载)。 | ||
| // 因此 Android 上不使用 extras 传递 audio-files,改为通过 change-list 命令方式(pre-open + post-open 双重保障)。 | ||
| // 注意:change-list 对 audio-files 属性值的 URL 中的冒号同样需要转义(旧版 mpv 会将冒号解析为 key:value 分隔符) | ||
| if (!Platform.isAndroid) { | ||
| extras['audio-files'] = '"$escapedAudio"'; | ||
| } | ||
| await player.command(['change-list', 'audio-files', 'clr', '']); | ||
| await player.command(['change-list', 'audio-files', 'set', escapedAudio]); |
There was a problem hiding this comment.
change-list audio-files is executed before player.open() on all platforms (including when a previous media is still loaded/paused). This mutates the player's current state and can have side effects (e.g., applying external audio to the currently loaded item) while it’s redundant on non-Android where extras['audio-files'] is still used. Consider limiting the pre-open change-list path to Android only, and/or moving the change-list calls to post-open() where you already re-apply them for Android.
| if (audioNormalization.isNotEmpty) { | ||
| // Android 上不使用 extras 传递 lavfi-complex,避免旧版 mpv 的 loadfile options 参数导致整体失败 | ||
| if (!Platform.isAndroid) { | ||
| extras['lavfi-complex'] = '"[aid1] $audioNormalization [ao]"'; | ||
| } | ||
| await player.command(['set', 'lavfi-complex', '[aid1] $audioNormalization [ao]']); | ||
| } |
There was a problem hiding this comment.
lavfi-complex is now set via player.command(['set', ...]) before player.open(). This changes the player’s state for the currently loaded (paused) media and is also redundant on non-Android where the same option is still passed via extras. To avoid unintended cross-media effects, consider: (1) using extras only on non-Android (no pre-open set), and (2) applying lavfi-complex via command only on Android (ideally post-open() if loadfile replace resets it similarly to audio-files).
| if (Platform.isAndroid) { | ||
| if (dataSource.audioSource case final audio? when (audio.isNotEmpty && !onlyPlayAudio.value)) { | ||
| final ea = audio.replaceAll(':', r'\:'); | ||
| await player.command(['change-list', 'audio-files', 'clr', '']); | ||
| await player.command(['change-list', 'audio-files', 'set', ea]); | ||
| } |
There was a problem hiding this comment.
The Android post-open() re-apply logic for audio-files is duplicated here and in refreshPlayer(). Consider extracting a small helper (e.g., _reapplyExternalAudioFilesIfNeeded(player)) to keep the escaping and conditions consistent and reduce the chance of future divergence.
|
这个问题可以在上游的PiliPlus复现吗?建议向上游提PR,让dom佬看看。。。( |
|
说实话,对于libmpv这块不是很熟。而且版本控制也会方便点,省的又要合并重复pr |
|
|
@TakChen 大佬合并下提交给上游提个PR吧 |
关联 Issue
closes #70
问题背景
在搭载 Hi3751V660 芯片(armeabi-v7a)的 Android TV 设备上,使用设备内置旧版 libmpv 播放含独立音频流的视频时,视频画面正常但完全无声音。PGC 影视内容(音视频合并文件)不受影响。
根因
经过三轮调试,定位到三个叠加的兼容性问题:
根因 1:旧版 mpv 不支持
loadfile的 options 参数media_kit的player.open(Media(url, extras: {...}))在底层调用:旧版 libmpv 无法解析
loadfile的第四个 options 字符串参数,整个命令失败,视频和音频均无法加载。根因 2:
loadfile replace会清除预设的audio-files属性即使跳过
extras,在player.open()前通过change-list audio-files set预设的值也会在loadfile replace执行时被清除,导致 pre-open 设置完全失效。根因 3:
change-list audio-files set <url>中 URL 的:未转义旧版 mpv 将选项值中的
:解析为 key-value 分隔符,https://...被错误分割,导致:修复方案
修改文件:
lib/plugin/pl_player/controller.dart1. Android 上跳过
extras,改用change-list命令2. Android 上
player.open()之后补设audio-files(post-open)同样的 post-open 补设逻辑也应用于
refreshPlayer()。3. URL 中
:转义为\:所有
change-list audio-files set调用均使用audio.replaceAll(':', r'\:')处理 URL。4. 恢复
lavfi-complex的全平台无条件执行移除之前为诊断目的误加的
kDebugMode || Platform.isAndroid限制,lavfi-complex恢复为所有平台正常处理。Android 上同样跳过extras传递。平台兼容性
audio-files传递方式change-listpre + postchange-listpre + postchange-listextras+change-listpreextras随loadfile生效,行为不变extras(;转义)+change-listpre;为列表分隔符,行为不变测试